<?php
/**
 * Created by PhpStorm.
 * User: 王松
 * Time: 2017/10/18 15:33
 */

namespace App\Project\Search;

use App\Models\MedicalRecord;
use App\Project\Search\Decorator\AuxiliaryDecorator;
use App\Project\Search\Decorator\CnDiagnoseDecorator;
use App\Project\Search\Decorator\DiagnoseDecorator;
use App\Project\Search\Decorator\MedicalDecorator;
use App\Project\Search\Decorator\PastDecorator;
use App\Project\Search\Decorator\PatientDecorator;
use App\Project\Search\Decorator\PhysicalDecorator;
use App\Project\Search\Exception\MedicalRecordSearchException;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * 病历搜索模块
 * @package App\Project\Search
 */
class Factory
{
    protected $condition;

    /**
     * @var \Illuminate\Database\Eloquent\Builder
     */
    protected $db;

    /**
     * @var bool 是否 select装饰表的字段
     */
    protected $extract = false;

    /**
     * @var array
     */
    protected $decorators = [
        'past'        => PastDecorator::class,
        'aux'         => AuxiliaryDecorator::class,
        'patient'     => PatientDecorator::class,
        'physical'    => PhysicalDecorator::class,
        'cn_diagnose' => CnDiagnoseDecorator::class,
        'diagnose'    => DiagnoseDecorator::class,
        'medical'     => MedicalDecorator::class,
    ];

    public function __construct($condition)
    {
        $this->setCondition($condition);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function getBuilder()
    {
        if ($this->condition)
            foreach ($this->decorators as $key => $decorator) {

                if (!array_key_exists($key, $this->condition)) {
                    continue;
                }

                $this->getDecorator($key)->getBuilder();
            }

        return $this->db;
    }

    /**
     * @param array $condition
     */
    public function setCondition(array $condition)
    {
        foreach ($condition as $key => $value) {
            Arr::set($this->condition, Str::replaceFirst('-', '.', $key), $value);
        }
    }

    /**
     * @param $name
     * @return \App\Project\Search\Decorator
     */
    public function getDecorator($name)
    {
        return new $this->decorators[$name]($this->condition[$name], $this->getDb(), $this->extract);
    }

    /**
     * @param array $decorators
     * @return $this
     */
    public function decorators(array $decorators)
    {
        $this->decorators = $decorators;

        return $this;
    }

    /**
     * @param \Illuminate\Database\Eloquent\Builder $db
     * @return $this
     * @throws \App\Project\Search\Exception\MedicalRecordSearchException
     */
    public function setDb(Builder $db)
    {
        if ($db->getModel() instanceof MedicalRecord) {
            $this->db = $db;

            return $this;
        }

        throw new MedicalRecordSearchException('Builder实例 应由 MedicalRecord 类创建。');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function getDb()
    {
        if (is_null($this->db)) {
            $this->db = (new MedicalRecord())->select(['st_medical_records.*']);
        }

        return $this->db;
    }

    /**
     * @param $result
     * @return \Illuminate\Support\Collection
     */
    public function translate($result)
    {
        $translate = new Translate($result);

        return $translate->getResult();
    }

    /**
     * @param bool $extract
     */
    public function setExtract($extract)
    {
        $this->extract = $extract;
    }

    public function reset()
    {
        Decorator::$joins = null;
    }
}